//
//  PrescriptionOrderPayController.swift
//  EyeVisionForPatients
//
//  Created by PMC on 2020/3/3.
//  Copyright © 2020 tao Tao. All rights reserved.
//

import UIKit

class PrescriptionOrderPayController: BaseViewController {
    
    var handlerClosure: (() -> Void)?
    
    private var viewModel = PrescriptionOrderDetailViewModel(mode: .pay)
    
    convenience init(orderId: String) {
        self.init()
        self.viewModel.orderId = orderId
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        title = "支付处方"
        loadData()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        setupNotification()
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        NotificationCenter.default.removeObserver(self)
    }
    
    override func makeUI() {
        super.makeUI()
        
        view.addSubview(tableView)
        tableView.snp.makeConstraints { make in
            make.edges.equalTo(view.safeAreaLayoutGuide).priority(.low)
            make.bottom.equalToSuperview()
        }
        
        view.addSubview(payBottomView)
        payBottomView.snp.makeConstraints { make in
            make.left.right.bottom.equalToSuperview()
            make.height.equalTo(bottomSafeH + 50)
        }
    }
    
    override func bindViewModel() {
        super.bindViewModel()
        
        viewModel.updateClosure = { [weak self, viewModel] in
            guard let self = self else { return }
            self.tableView.reloadData()
            self.payBottomView.bind(to: viewModel)
            self.payBottomView.showTestMedicalInsurancePayBtn()
        }
        
        
    }
    
    private lazy var payBottomView: PrescriptionOrderBottomPayView = {
        let view = UINib.loadViewFrom(PrescriptionOrderBottomPayView.self)
        view.delegate = self
        return view
    }()
    
    private lazy var tableView: UITableView = {
        let tableView = UITableView(frame: .zero, style: .grouped)
        tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: bottomSafeH + 50, right: 0)
        tableView.backgroundColor = .background
        tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 1))
        tableView.tableFooterView = UIView()
        tableView.separatorStyle = .none
        
        tableView.delegate = self
        tableView.dataSource = self
        
        tableView.register(PrescriptionOrderReceiveCell.nibForCell(),
                           forCellReuseIdentifier: PrescriptionOrderReceiveCell.reuseIdentifier())
        tableView.register(PrescriptionOrderAddressCell.nibForCell(),
                           forCellReuseIdentifier: PrescriptionOrderAddressCell.reuseIdentifier())
        tableView.register(PrescriptionOrderPatientInfoPayCell.nibForCell(),
                           forCellReuseIdentifier: PrescriptionOrderPatientInfoPayCell.reuseIdentifier())
        tableView.register(PrescriptionOrderDrugsListCell.nibForCell(),
                           forCellReuseIdentifier: PrescriptionOrderDrugsListCell.reuseIdentifier())
        tableView.register(PrescriptionOrderDrugsUseUrgeCell.nibForCell(),
                           forCellReuseIdentifier: PrescriptionOrderDrugsUseUrgeCell.reuseIdentifier())
        tableView.register(PrescriptionOrderDoctorInfoPayCell.nibForCell(),
                           forCellReuseIdentifier: PrescriptionOrderDoctorInfoPayCell.reuseIdentifier())
        return tableView
    }()
}

extension PrescriptionOrderPayController {
    private func loadData() {
        viewModel.getPrescriptionOrderDetail()
    }
    
    private func setupNotification() {
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(wechatPaySuccess(_:)),
                                               name: NotiName.wechatPaySuccess,
                                               object: nil)
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(wechatPayFailure(_:)),
                                               name: NotiName.wechatPayFailure,
                                               object: nil)
    }
}

extension PrescriptionOrderPayController: UITableViewDataSource, UITableViewDelegate {
    func numberOfSections(in tableView: UITableView) -> Int {
        return viewModel.numberOfSections
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return viewModel.viewModel(at: section).numberOfRows
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let viewModel = viewModel.viewModel(at: indexPath.section)
        
        switch viewModel.mode {
        case .receiveType:
            let cell = tableView.dequeueReusableCell(withIdentifier: PrescriptionOrderReceiveCell.reuseIdentifier(),
                                                     for: indexPath) as! PrescriptionOrderReceiveCell
            cell.bind(to: viewModel)
            cell.handlerClosure = { [weak self] viewModel in
                guard let self = self else { return }
                self.viewModel.update(with: viewModel)
                self.tableView.reloadData()
            }
            return cell
        case .address:
            let cell = tableView.dequeueReusableCell(withIdentifier: PrescriptionOrderAddressCell.reuseIdentifier(),
                                                     for: indexPath) as! PrescriptionOrderAddressCell
            cell.bind(to: viewModel)
            return cell
        case .patientInfoForPay:
            let cell = tableView.dequeueReusableCell(withIdentifier: PrescriptionOrderPatientInfoPayCell.reuseIdentifier(),
                                                     for: indexPath) as! PrescriptionOrderPatientInfoPayCell
            cell.bind(to: viewModel)
            return cell
        case .drugs:
            let cell = tableView.dequeueReusableCell(withIdentifier: PrescriptionOrderDrugsListCell.reuseIdentifier(),
                                                     for: indexPath) as! PrescriptionOrderDrugsListCell
            cell.bind(to: viewModel)
            return cell
        case .drugAdvice:
            let cell = tableView.dequeueReusableCell(withIdentifier: PrescriptionOrderDrugsUseUrgeCell.reuseIdentifier(),
                                                     for: indexPath) as! PrescriptionOrderDrugsUseUrgeCell
            cell.bind(to: viewModel)
            return cell
        case .doctorInfoForPay:
            let cell = tableView.dequeueReusableCell(withIdentifier: PrescriptionOrderDoctorInfoPayCell.reuseIdentifier(),
                                                     for: indexPath) as! PrescriptionOrderDoctorInfoPayCell
            cell.bind(to: viewModel)
            return cell
        default:
            return UITableViewCell()
        }
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return viewModel.cellHeight(at: indexPath)
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let mode = viewModel.viewModel(at: section).mode
        switch mode {
        case .receiveType,
             .address,
             .patientInfoForPay: return UIView()
        default:                 return nil
        }
    }

    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return nil
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return viewModel.headerHeight(in: section)
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 0.001
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        let viewModel = viewModel.viewModel(at: indexPath.section)
        
        if viewModel.mode == .address && viewModel.receiveType == .express {
            let addressVc = FamilyAddressController()
            navigationController?.pushViewController(addressVc, animated: true)
            addressVc.selectClosure = { [weak self] vm in
                guard let self = self else { return }
                self.viewModel.updateReceiver(with: vm)
                self.tableView.reloadRows(at: [indexPath], with: .automatic)
            }
        }
    }
}

extension PrescriptionOrderPayController: DrugsPayBottomViewDelegate {
    func didTappedPayAction(type: NewAdvisoryGenerateOrderEnum, view: PrescriptionOrderBottomPayView) {
        if !viewModel.receiverNotEmpty {
            HUDTool.show(message: "请填写收货人地址")
            return
        }
        switch type {
        case .wechatPay:
            wechatSubmitOrder()
        case .medicalInsurancePay:
            medicalInsurancePay()
        }
    }
    
    func medicalInsurancePay() {
        guard let query = "orderId=\(viewModel.orderId)&receiveId=\(viewModel.receiverId)&getType=\(viewModel.receiveType.rawValue)&token=\(UserDefaults.token)".addingPercentEncoding(withAllowedCharacters: .afURLQueryAllowed),
              let url = URL(string: "alipays://platformapi/startapp?appId=2021003169675062&page=&query=\(query)") else { return }
        if UIApplication.shared.canOpenURL(url) {
            navigationController?.pushViewController(PrescriptionOrderPayResultController(orderId: viewModel.orderId, preId: viewModel.prescriptionId), animated: true)
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
                UIApplication.shared.open(url)
            })
        } else {
            YSGToast.showToast(text: "需安装支付宝APP后使用", type: .warring)
        }
    }
    
    /// 选择支付方式
    private func showSelectPayStyleView(_ model: WXPayResult) {
        let styleView = UINib.loadViewFrom(SelectPayStyleView.self)
        styleView.show()
        styleView.configure(cost: viewModel.price, time: "30")
        styleView.handlerClosure = { [weak self] style in
            guard let self = self else { return }
            switch style {
            case .wechat:
                self.wechatPay(model)
            }
        }
    }
    
    private func wechatSubmitOrder() {
        HUDTool.showActivity()
        WXApiRequestHandler.wxPaySubmitOrder(orderId: viewModel.orderId,
                                             orderAmount: viewModel.price,
                                             receiveId: viewModel.receiverId,
                                             orderType: .prescription,
                                             receiveType: viewModel.receiveType,
                                             success: { (wxModel) in
            HUDTool.hideActivity()
            self.showSelectPayStyleView(wxModel)
        }) { (errorMsg, code) in
            HUDTool.hideActivity()
            HUDTool.showError(message: errorMsg)
            if code == "2032107" {
                self.navigationController?.popViewController(animated: true)
                self.handlerClosure?()
            }
        }
    }
    
    /// 微信支付
    private func wechatPay(_ model: WXPayResult) {
        if !WXApi.isWXAppInstalled() {
            HUDTool.show(message: "未安装微信")
            return
        }
        
        WXApiRequestHandler.generateWXPayOrder(model: model)
    }
    
    @objc private func wechatPaySuccess(_ noti: Notification) {
        YSGLog("处方药支付：\(viewModel.orderId)")
        PayViewModel.queryOrderStatus(orderId: viewModel.orderId) { (errorMsg) in
            if errorMsg != nil {
                HUDTool.show(message: "订单支付失败")
                self.navigationController?.popViewController(animated: true)
            } else {
                self.pushPayResultVc()
            }
        }
    }
    
    @objc private func wechatPayFailure(_ noti: Notification) {
        HUDTool.show(message: "订单支付失败")
        navigationController?.popViewController(animated: true)
    }
    
    private func pushPayResultVc() {
        let payResultVc = PayResultViewController(with: PublishViewModel(), orderType: .prescription)
        removeCurrentVcWhenPush(payResultVc)
    }
}
